<?php
	class GP_dbcache extends PDO
	{
		static $_instance;
		var $requetes = array();
		var $temps_requetes = 0;
		
		// singleton
		public function &getInstance() 
		{
			if (!self::$_instance instanceof self)
				self::$_instance = new self();
			return self::$_instance;
		}
		
		function __construct()
		{
			parent::__construct('sqlite::memory:', null, null, array(PDO::ATTR_PERSISTENT => true) );
		}
		
		public function requete($sql)
		{
			if(!empty($sql)) {
				$temps1 = $this->_getMicroTime();
				
				try {
					$res = parent::query($sql);
					$this->requetes[] = $sql;
					if($res === false)
						GP_debug::erreur(parent::errorInfo(), 1);
				} catch (PDOException $e) {
					$err = 'Erreur : <br />';
					$err .= '<pre>';
					$err .= 'Error: ' . $e->getMessage() . '<br />';
					$err .= 'Erreur: ' . $e->getCode() . '<br />';
					$err .= 'Fichier: ' . $e->getFile() . '<br />';
					$err .= 'Ligne: ' . $e->getLine() . '<br />';
					$err .= 'Trace: ' . $e->getTraceAsString();
					$err .= '</pre>';

					GP_debug::erreur($err, 1);
				}
				
				$temps2 = $this->_getMicroTime();
				$this->temps_requetes = (float) $this->temps_requetes + (float) ($temps2 - $temps1);
				return $res;
			}
			else
				return false;
		}
		
		public function fetchArray($sql)
		{
			$temps1 = $this->_getMicroTime();
			$this->requetes[] = $sql;
			
			try {
				$res = parent::prepare($sql);
				$rs = $res->execute();
				if($rs === false) {
					$erreur = $sql;
					$erreur .= '<p />';
					
					$erreur_info = $res->errorInfo();
					
					$erreur .= 'Erreur ' . $erreur_info[1] . ' ' . sl($erreur_info[2]);
					
					GP_debug::erreur($erreur, 1);
				}
				$res->setFetchMode(parent::FETCH_ASSOC);
				$tab = $res->fetchAll();
				$res->closeCursor();

			} catch (PDOException $e) {
				$err = 'Erreur : <br />';
				$err .= '<pre>';
				$err .= 'Error: ' . $e->getMessage() . '<br />';
				$err .= 'Erreur: ' . $e->getCode() . '<br />';
				$err .= 'Fichier: ' . $e->getFile() . '<br />';
				$err .= 'Ligne: ' . $e->getLine() . '<br />';
				$err .= 'Trace: ' . $e->getTraceAsString();
				$err .= '</pre>';

				GP_debug::erreur($err, 1);
			}
			
			$temps2 = $this->_getMicroTime();
			$this->temps_requetes = (float) $this->temps_requetes + (float) ($temps2 - $temps1);
			return $tab;
		}
		
		public function fetchArray_one($sql)
		{
			$tab = self::fetchArray($sql);
			list($subtab) = $tab;
			return $subtab;
		}
		
		public function fetchRow($sql)
		{
			$temps1 = $this->_getMicroTime();
			$this->requetes[] = $sql;
			
			try {
				$res = parent::prepare($sql);
				$rs = $res->execute();
				if($rs === false) {
					$erreur = $sql;
					$erreur .= '<p />';
					
					$erreur_info = $res->errorInfo();
					
					$erreur .= 'Erreur ' . $erreur_info[1] . ' ' . sl($erreur_info[2]);
					
					GP_debug::erreur($erreur, 1);
				}
				$res->setFetchMode(parent::FETCH_NUM);
				$tab = $res->fetchAll();
				$res->closeCursor();
			} catch (PDOException $e) {
				$err = 'Erreur : <br />';
				$err .= '<pre>';
				$err .= 'Error: ' . $e->getMessage() . '<br />';
				$err .= 'Erreur: ' . $e->getCode() . '<br />';
				$err .= 'Fichier: ' . $e->getFile() . '<br />';
				$err .= 'Ligne: ' . $e->getLine() . '<br />';
				$err .= 'Trace: ' . $e->getTraceAsString();
				$err .= '</pre>';

				GP_debug::erreur($err, 1);
			}
			
			$temps2 = $this->_getMicroTime();
			$this->temps_requetes = (float) $this->temps_requetes + (float) ($temps2 - $temps1);
			return $tab;
		}
		
		public function existe($sql)
		{
			$tab = self::fetchRow($sql);
			if (count($tab))
				return true;
			return false;
		}
		
		public function fetchRow_one($sql)
		{
			$tab = self::fetchRow($sql);
			list($subtab) = $tab;
			return $subtab;
		}
		
		public function LastId()
		{
			return parent::lastInsertId(); 
		}
		
		public function affected_rows($sql)
		{
			$temps1 = $this->_getMicroTime();
			$this->requetes[] = $sql;
			
			try {
				$res = parent::prepare($sql);
				$rs = $res->execute();
				if($rs === false)
				{
					$erreur = $sql;
					$erreur .= '<p />';
					
					$erreur_info = $res->errorInfo();
					
					$erreur .= 'Erreur ' . $erreur_info[1] . ' ' . sl($erreur_info[2]);
					
					GP_debug::erreur($erreur, 1);
				}
				$nb = $res->rowCount();
				$res->setFetchMode(parent::FETCH_NUM);
				$tab = $res->fetchAll();
			} catch (PDOException $e) {
				$err = 'Erreur : <br />';
				$err .= '<pre>';
				$err .= 'Error: ' . $e->getMessage() . '<br />';
				$err .= 'Erreur: ' . $e->getCode() . '<br />';
				$err .= 'Fichier: ' . $e->getFile() . '<br />';
				$err .= 'Ligne: ' . $e->getLine() . '<br />';
				$err .= 'Trace: ' . $e->getTraceAsString();
				$err .= '</pre>';

				GP_debug::erreur($err, 1);
			}
			
			$temps2 = $this->_getMicroTime();
			$this->temps_requetes = (float) $this->temps_requetes + (float) ($temps2 - $temps1);
			return $nb;
		}
		
		public function metadata($sql, $num)
		{
			$temps1 = $this->_getMicroTime();
			$this->requetes[] = $sql;
			$res = parent::query($sql);
			if($res === false) {
				$erreur = $sql;
				$erreur .= '<p />';
					
				$erreur_info = $res->errorInfo();
					
				$erreur .= 'Erreur ' . $erreur_info[1] . ' ' . sl($erreur_info[2]);
					
				GP_debug::erreur($erreur, 1);
			}
			$metadata = $res->getColumnMeta($num);
			
			$temps2 = $this->_getMicroTime();
			$this->temps_requetes = (float) $this->temps_requetes + (float) ($temps2 - $temps1);
			
			return $metadata;
		}
		
		public function voir_requete($num = null)
		{
			if(empty($this->requetes))
				return false;
			if(is_null($num))
				$num = count($this->requetes) - 1;
			return $this->requetes[$num];
		}
		
		public function _getMicroTime() 
		{
			list($usec, $sec) = explode(" ", microtime(), 2);
			return ((float) $usec + (float) $sec);
		}
		
		public function mise_en_cache($sql)
		{
			$id_cache = md5($sql);
			$en_cache = GP_cache::en_cache($id_cache);
			if ($en_cache)
				return unserialize(GP_cache::charger($id_cache));
			else {
				$donnees = $this->fetchArray($sql);
				$resultats_pour_cache = serialize($donnees);
				GP_cache::creer($id_cache, $resultats_pour_cache);
				return $donnees;
			}
		}
		
		public function heureSQL()
		{
			$tab = self::fetchRow("SELECT NOW()");
			list($subtab) = $tab;
			$heuresql = $subtab[0];
			return GP_date::dateSQL2Unix($heuresql);
		}
		
		function inserer($table, $valeurs) 
		{
			if (is_array($valeurs) && (count ($valeurs) > 0))  {
				$original_valeurs = $valeurs;
			
				foreach ($valeurs as $key => $val) { 
					$champs[] = $key;
					$valeurs[$key] = "'" . GP_fonctions::mysql_chaine($val) . "'";
				}

				$champs_texte = implode(",", $champs);
				$valeurs_texte = implode(",", $valeurs);
			}
			
			$requete = "INSERT INTO $table ($champs_texte) VALUES ($valeurs_texte);";
			$resultat = self::requete($requete);

			if (isset($original_valeurs["id"]))
				$id = $original_valeurs["id"];
			else
				$id = self::LastId();
				
			return $id;
		}

		function db_update($table, $where, $table_data) 
		{ 
			if ($table && isset($where) && strlen($where)) {
				$requete = "UPDATE $table SET";
				
				if (is_array($table_data)) {
					foreach ($table_data as $champ => $valeur) 
						$requete_aux[] = "$champ = '" . GP_fonctions::mysql_chaine($valeur) . "'";
					
					$requete_options = join($requete_aux, ",");
							
					$requete .= " $requete_options WHERE " . GP_fonctions::mysql_chaine($where);

					$resultat = self::requete($requete);
				}
			}
				
			$resultat = (is_resource($resultat)) ? true : $resultat;
			return $resultat;
		}
		
		function champs_table($table)
		{
			$retour = array();
			
			$tab = self::fetchArray("SHOW COLUMNS FROM " . $table);
			$nb = nbres($tab);
			for ($i = 0 ; $i < $nb ; $i++)
				$retour[] = data($tab, $i, 'Field');
			return $retour;
		}
		
		function champs_table_type($table)
		{			
			$retour = array();
			
			$tab = self::fetchArray("SHOW COLUMNS FROM " . $table);
			$nb = nbres($tab);
			for ($i = 0 ; $i < $nb ; $i++) {
				$champ = data($tab, $i, 'Field');
				$retour[$champ] = data($tab, $i, 'Type');
			}
			return $retour;
		}
	}
?>